package it.softphone.commons.spring;


import it.softphone.commons.exception.NullParameterException;

import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletContext;

import org.springframework.config.java.context.JavaConfigApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

/**
 * 
 * @author softphone
 *
 */
public class ApplicationConfig {
	
	public static class Context extends JavaConfigApplicationContext {
		java.util.Map<String,Object> attributes = new ConcurrentHashMap<String, Object>(5);
		
		protected Context() {
			super();
		}

		public void setAttribute( String name, Object value) {
			attributes.put( name, value);
		}
		
		@SuppressWarnings("unchecked")
		public <T> T getAttribute( String name ) {
			return (T)attributes.get( name );
		}

	}
	
	private static 	Context context = null;
	
	public static Context getContext( boolean throwException ) throws IllegalStateException {
		synchronized (ApplicationConfig.class) {
		if( context==null && throwException) throw new IllegalStateException( "context is not initialized yet!");
		return context;

		}
	}
	
	public static final <T> T getBean( Class<T> type ) {
		return getContext(true).getBean(type);
	}

	public static final <T> T getBean( Class<T> type, String name ) {
		return getContext(true).getBean(type, name);
	}

	public static Context init( ) {
		synchronized (ApplicationConfig.class) {
			if( context!=null ) throw new IllegalStateException( "context is already initialized!");
			context = new Context();
		}
		return context;
	}
	
	public static final Context init( final ServletContext ctx ) {
		synchronized (ApplicationConfig.class) {
			if( context!=null ) throw new IllegalStateException( "context is already initialized!");
			context = new Context() {

				@Override
				protected Resource getResourceByPath(String path) {
					if( path==null ) throw new NullParameterException("path");
					if( path.length()==0 ) throw new IllegalArgumentException("path is zero length");
					
					char c = path.charAt(0);
					if( c=='/' ) {

						String realPath = ctx.getRealPath(path);
						
						java.io.File file = new java.io.File( realPath );
						
						return new FileSystemResource(file);

					}
					return super.getResourceByPath(path);
				}
				
			};
			context.setAttribute( ServletContext.class.getName(), ctx);
		}		
		return context;
	}

	public final static ServletContext getServletContext( ) {
		
		Context context = getContext( true );

		return context.getAttribute(ServletContext.class.getName());
	}
	

	
	public static void shutdown() {
		
		context.destroy();
		context = null;
	}
	
	protected ApplicationConfig() {
	}

}
